package cn.stylefeng.guns.modular.robot.service.impl;

import cn.stylefeng.guns.modular.robot.entity.CdInfo;
import cn.stylefeng.guns.modular.robot.entity.vo.req.OrderInfoReq;
import cn.stylefeng.guns.modular.robot.entity.vo.req.SubmitCdReq;
import cn.stylefeng.guns.modular.robot.entity.vo.resp.PullOrderResp;
import cn.stylefeng.guns.modular.robot.mapper.CdInfoMapper;
import cn.stylefeng.guns.modular.robot.service.CdInfoService;
import cn.stylefeng.guns.modular.robot.utils.RobotUtils;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.telegram.telegrambots.bots.TelegramLongPollingBot;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class CdInfoServiceImpl extends ServiceImpl<CdInfoMapper, CdInfo> implements CdInfoService {

    @Resource
    private TelegramLongPollingBot bot;

    @Override
    public void createCdInfo(String replace, Long receiveGroupId) {
        String[] split = replace.split("\n");
        CdInfo cdInfo = new CdInfo();
        cdInfo.setGroupId(receiveGroupId);
        BigDecimal amount = null;
        for (String line : split) {
            try {
                if (line.contains("交易金额：")) {
                    amount = BigDecimal.valueOf(Double.parseDouble(line.replace("交易金额：", "")));
                    cdInfo.setAmount(amount);
                }
                if (line.contains("转账人：")) {
                    cdInfo.setUserName(line.replace("转账人：", ""));
                }
                if (line.contains("转账时间：")) {
                    cdInfo.setOrderCreateTime(DateUtils.parseDate(line.replace("转账时间：", ""), "yyyy-MM-dd HH:mm:ss"));
                }
            } catch (Exception e) {
                e.getMessage();
            }
        }
        List<CdInfo> cdInfos = lambdaQuery()
                .eq(CdInfo::getAmount, cdInfo.getAmount())
                .eq(CdInfo::getUserName, cdInfo.getUserName())
                .eq(CdInfo::getOrderCreateTime, cdInfo.getOrderCreateTime())
                .list();
        String msg = "查单失败！";
        if (!CollectionUtils.isEmpty(cdInfos)) {
            msg = "查单成功！";
        } else {
            Date orderCreateTime = cdInfo.getOrderCreateTime();
            long time = orderCreateTime.getTime();
            Date date = new Date(time + 60000);
            cdInfos = lambdaQuery()
                    .eq(CdInfo::getAmount, cdInfo.getAmount())
                    .eq(CdInfo::getUserName, cdInfo.getUserName())
                    .lt(CdInfo::getOrderCreateTime, date)
                    .gt(CdInfo::getOrderCreateTime, orderCreateTime)
                    .list();
            if (!CollectionUtils.isEmpty(cdInfos)) {
                msg = "疑似查单成功！";
            }
        }
        RobotUtils.sendText(receiveGroupId, msg, bot);
    }

    @Override
    public void cdNotify(CdInfo cdInfo, Boolean isAccurate) {
        CdInfo ci = getById(cdInfo.getId());
        updateById(ci);
        if (isAccurate) {
            RobotUtils.sendText(cdInfo.getGroupId(), "查单成功！", bot);
        } else {
            RobotUtils.sendText(cdInfo.getGroupId(), "疑似查单成功！", bot);
        }
    }

    @Override
    public PullOrderResp pullOrder(List<OrderInfoReq> orderInfoReqs) {
        PullOrderResp resp = new PullOrderResp();
        IPage<CdInfo> page = lambdaQuery()
                .eq(CdInfo::getIsHandle, true)
                .orderByDesc(CdInfo::getOrderCreateTime)
                .page(new Page<>(1, 1));
        //
        if (page == null || CollectionUtils.isEmpty(page.getRecords())) {
            resp.setIsContinue(true);
        } else {
            List<CdInfo> records = page.getRecords();
            CdInfo cdInfo = records.get(0);
            OrderInfoReq orderInfoReq = orderInfoReqs.get(orderInfoReqs.size() - 1);
            if (cdInfo.getOrderCreateTime().before(orderInfoReq.getCreateTime())) {
                resp.setIsContinue(true);
            } else {
                resp.setIsContinue(false);
            }
        }
        List<CdInfo> cdInfos = new ArrayList<>();
        for (OrderInfoReq orderInfoReq : orderInfoReqs) {
            int small = orderInfoReq.getAmount().intValue() % 100;
            BigDecimal amount = orderInfoReq.getAmount().subtract(BigDecimal.valueOf(small));
            List<CdInfo> oldCdInfos = lambdaQuery()
                    .eq(CdInfo::getAmount, amount)
                    .eq(CdInfo::getAmountSmall,small)
                    .eq(CdInfo::getOrderCreateTime, orderInfoReq.getCreateTime())
                    .eq(CdInfo::getUserName, orderInfoReq.getUserName())
                    .list();
            if (!CollectionUtils.isEmpty(oldCdInfos)) {
                continue;
            }
            List<CdInfo> list = lambdaQuery()
                    .eq(CdInfo::getIsCallBack,false)
                    .eq(CdInfo::getAmountSmall, small)
                    .eq(CdInfo::getAmount, amount)
                    .list();
            if (CollectionUtils.isEmpty(list)) {
                CdInfo cdInfo = new CdInfo();
                cdInfo.setCarNum(orderInfoReq.getCarNum());
                cdInfo.setAmount(amount);
                cdInfo.setOrderCreateTime(orderInfoReq.getCreateTime());
                cdInfo.setRobotId(orderInfoReq.getRobotId());
                cdInfo.setUserName(orderInfoReq.getUserName());
                cdInfo.setAmountSmall(small);
                cdInfo.setCreateTime(new Date());
                cdInfo.setUpdateTime(new Date());
                cdInfo.setIsHandle(false);
                cdInfo.setIsCallBack(true);
                cdInfos.add(cdInfo);
            } else {
                CdInfo cdInfo = list.get(0);
                cdInfo.setCarNum(orderInfoReq.getCarNum());
                cdInfo.setAmount(amount);
                cdInfo.setOrderCreateTime(orderInfoReq.getCreateTime());
                cdInfo.setRobotId(orderInfoReq.getRobotId());
                cdInfo.setUserName(orderInfoReq.getUserName());
                cdInfo.setUpdateTime(new Date());
                cdInfo.setIsHandle(true);
                cdInfo.setIsCallBack(true);
                updateById(cdInfo);
            }
        }
        if (CollectionUtils.isEmpty(cdInfos)) {
            resp.setIsContinue(false);
        }
        saveBatch(cdInfos);
        if (!resp.getIsContinue()) {
            lambdaUpdate()
                    .set(CdInfo::getIsHandle, true)
                    .eq(CdInfo::getIsHandle, false)
                    .update();
        }
        return resp;
    }

    @Override
    public CdInfo getSmallAmount(String accountNumber, String accountName, String accountMoney) {
        List<CdInfo> cdInfos = lambdaQuery()
                .eq(CdInfo::getAmount, accountMoney)
                .list();
        CdInfo cdInfo = new CdInfo();
        if (CollectionUtils.isEmpty(cdInfos)) {
            cdInfo.setAmountSmall(0);
        } else {
            Set<Integer> amountSmalls = cdInfos.stream().map(CdInfo::getAmountSmall).collect(Collectors.toSet());
            for (int i = 0; i < 99; i++) {
                if (!amountSmalls.contains(i)) {
                    cdInfo.setAmountSmall(i);
                    break;
                }
            }
            if (cdInfo.getAmountSmall() == null) {
                throw new RuntimeException("该金额小数点已经用完！");
            }
        }
        cdInfo.setCarNum(accountNumber);
        cdInfo.setAmount(new BigDecimal(accountMoney));
        cdInfo.setUserName(accountName);
        cdInfo.setCreateTime(new Date());
        cdInfo.setUpdateTime(new Date());
        cdInfo.setIsHandle(false);
        cdInfo.setIsCallBack(false);
        save(cdInfo);
        return cdInfo;
    }

    @Override
    public void submitCd(SubmitCdReq submitCdReq) {
        CdInfo cdInfo = getById(submitCdReq.getId());
        cdInfo.setCarNum(submitCdReq.getAccount());
        cdInfo.setAmount(submitCdReq.getAmount());
        cdInfo.setAmountSmall(submitCdReq.getAmountSmall());
        cdInfo.setUserName(submitCdReq.getAccountName());
        cdInfo.setOrderId(submitCdReq.getOrderId());
        cdInfo.setIsHandle(false);
        updateById(cdInfo);
    }

    @Override
    public void pullList(List<CdInfo> cdInfos) {
        for (CdInfo cdInfo : cdInfos) {
            List<CdInfo> list = lambdaQuery()
                    .eq(CdInfo::getOrderCreateTime, cdInfo.getOrderCreateTime())
                    .eq(CdInfo::getUserName, cdInfo.getUserName())
                    .eq(CdInfo::getAmount, cdInfo.getAmount())
                    .list();
            if(!CollectionUtils.isEmpty(list)){
                continue;
            }
            save(cdInfo);
        }
    }
}
